const express = require('express');
const app = express();
const multer = require('multer');
const Jimp = require('jimp');
const fs = require('fs');
const sharp = require('sharp');
const upload = multer({ dest: 'uploads/' });
const path = require('path')
const bodyParser = require('body-parser');
const qrcode = require('qrcode');
const request = require('request');
const morgan = require('morgan')
const urlencodedParser = bodyParser.urlencoded({ extended: false });

const port = 3000
const baseUrl = 'http://localhost:3000/' //定义程序域名/IP地址

app.post('/decode', urlencodedParser, (req, res) => {
  const { image_path } = req.body
  const options = {
    method: 'POST',
    url: 'https://qrdetector-api.cli.im/v1/detect_binary',
    headers: {
      Host: 'qrdetector-api.cli.im',
      Origin: 'https://cli.im',
      Pragma: 'no-cache',
      Referer: 'https://cli.im/deqr',
      'content-type': 'application/x-www-form-urlencoded'
    },
    form: {
      remove_background: '1',
      image_path
    }
  };

  request(options, function (error, response, body) {
    if (error) throw new Error(error);
    const data = JSON.parse(body);
    if (data.status != 1) return res.json({ code: 400, msg: '解码错误！' });
    return res.json({ code: 200, msg: '解码完成！', data: data.data.qrcode_content })
  });
});

app.post('/crop-image', upload.single('file'), async (req, res) => {
  try {
    const { file } = req;
    // return console.log(file.width);
    // 使用Sharp库读取上传的图片文件
    const image = sharp(file.path);
    const metadata = await image.metadata();
    const width = metadata.width
    const height = metadata.height
    const clone = [{ x: width * 0.3, y: height * 0.16 }, { x: width * 0.7, y: height * 0.57 }];
    const x = clone[1].x - clone[0].x
    const y = clone[1].y - clone[0].y
    // 裁剪图片并保存为png格式
    const resizedImage = await image
      .extract({ left: Math.trunc(clone[0].x), top: Math.trunc(clone[0].y), width: Math.trunc(x), height: Math.trunc(y) })
      .toFormat('png')
      .toBuffer();

    // 生成保存文件的路径和文件名
    const savePath = path.join(__dirname, 'public/uploads');
    const saveFileName = `${Date.now()}-zsm.png`;

    // 将裁剪后的图片保存到本地
    fs.writeFileSync(path.join(savePath, saveFileName), resizedImage);

    // 返回保存成功的结果
    res.json({ code: 200, url: `/uploads/${saveFileName}` });
  } catch (error) {
    console.error(error);
    res.json({ code: 400, message: error.message });
  } finally {
    // 删除临时文件
    fs.unlink(req.file.path, (err) => {
      if (err) {
        console.error(err);
      }
    });
  }
});

app.post('/create', urlencodedParser, (req, res) => {
  const { Name, qqpay, wxpay, alipay } = req.body
  const time = Date.now()
  const json = {
    Name,
    qqpay,
    wxpay,
    alipay
  }
  const Str = JSON.stringify(json)
  const savePath = path.join(__dirname, 'data');
  const saveFileName = `${Date.now()}.json`;
  const file = path.join(savePath, saveFileName)

  fs.writeFile(file, Str, async (err) => {
    if (err) {
      return res.json({ code: 500, err })
    } else {
      const url = `${baseUrl}/qr?id=${time}`
      const uin = qqpay.match(/u=(\d+)/)[1]
      try {
        // QQ头像圆形处理
        const image = await Jimp.read(`http://q.qlogo.cn/headimg_dl?dst_uin=${uin}&spec=160&img_type=jpg`)
        const size = Math.min(image.bitmap.width, image.bitmap.height);
        const x = (image.bitmap.width - size) / 2;
        const y = (image.bitmap.height - size) / 2;
        const avatarBuffer = await image.crop(x, y, size, size).resize(152, 152).circle().getBufferAsync(Jimp.MIME_PNG)

        // 生成SVG二维码
        // 生成SVG格式的二维码
        const codeSvg = await qrcode.toString(url, {
          type: 'svg',
          errorCorrectionLevel: 'H',
          margin: 1,
          width: 370
        })

        // 将SVG转换为PNG格式的图像
        const codePng = await sharp(Buffer.from(codeSvg))
          .png({
            quality: 100, // 控制二维码质量
            compressionLevel: 0 // 控制二维码压缩级别
          })
          .toBuffer()
        // 加载模板图像并添加二维码和头像
        const template = await sharp('img/template/qr1.png')
        const qrImage = await sharp(codePng)
        const avatar = await sharp(avatarBuffer)
        const qrSize = { width: 370, height: 370 }
        const avatarSize = { width: 152, height: 152 }
        const qrPosition = { left: 351, top: 470 }
        const avatarPosition = { left: 460, top: 138 }
        const qrBuffer = await template
          .composite([{ input: await qrImage.resize(qrSize.width, qrSize.height).toBuffer(), ...qrPosition }, { input: await avatar.resize(avatarSize.width, avatarSize.height).toBuffer(), ...avatarPosition }])
          .png()
          .toBuffer()
        const qrBase64 = qrBuffer.toString('base64')
        return res.json({ code: 200, data: 'data:image/png;base64,' + qrBase64 })
        // Do something with qrBase64 here
      } catch (err) {
        console.log(err);
      }

    }
  })

})

app.get('/qrdata', (req, res) => {
  try {
    const { id } = req.query
    const Path = path.join(__dirname, 'data');
    const FileName = `${id}.json`;
    const file = path.join(Path, FileName)
    fs.readFile(file, 'utf8', (err, data) => {
      if (err) {
        return res.json({ code: 500, msg: '数据文件已丢失！' })
      }
      if (data) {
        return res.json({ code: 200, data: JSON.parse(data) })
      }
      return res.json({ code: 500, msg: '数据文件已损坏，请重新生成' })

    })
  } catch (err) {
    console.log(err)
  }

})


app.use(morgan('dev'))
app.use(express.static(__dirname + '/public/', { index: "index.html" })); // __dirname为当前index.js所在的绝对路径
app.listen(port, () => {
  console.log(`Example app listening on port ${port}! Server running at http://localhost:${port}/`);
})